package com.qunar.train.mock.config;

import com.qunar.train.mock.util.AegisLog;
import com.qunar.train.mock.util.ConfigHandle;
import com.qunar.train.mock.util.FileAndDirDeepDeletion;
import com.qunar.train.mock.util.QunarFileUtil;

import java.io.File;
import java.util.Map;

import qunar.tc.qconfig.client.Feature;
import qunar.tc.qconfig.client.MapConfig;

import static com.qunar.train.mock.config.ChangeQconfigEnv.changeQconfigEnv;
import static com.qunar.train.mock.config.MockQconfig.getAppCode;

/**
 * Created by zhangqianqian.zhang on 2019/3/26.
 */
public class QconfigSingleFileDownload {
    /**
     * download online Qconfigures files, run with online, then turned to offline 模块需要的文件名，默认\t\n间隔
     *
     * @param args
     */
    private static String resourcesPath = Class.class.getClass().getResource("/").getPath().split("/target")[0] + "/src/test/resources/" + "qconfig_test/";
    private static String qconfigTargetDir = Class.class.getClass().getResource("/").getPath().split("/target")[0] + "/target/test-classes/" + "qconfig_test/";
    private static Boolean isNewVersion = true;
    private static String fileName = "";
    private static String groupName = getAppCode();
    private static Boolean isReWrite = false;
    private static Boolean isFileExsist = true;


    public QconfigSingleFileDownload(String fileName, Boolean isNewVersion, Boolean isReWrite) {
        this.fileName = fileName.toLowerCase();
        this.isNewVersion = isNewVersion;
        this.isReWrite = isReWrite;
        this.isFileExsist = checkIfFileExsist(resourcesPath + groupName);
        init();
    }

    public QconfigSingleFileDownload(String fileName, String groupName, Boolean isNewVersion) {
        this.fileName = fileName.toLowerCase();
        this.groupName = groupName;
        this.isNewVersion = isNewVersion;
        this.isFileExsist = checkIfFileExsist(resourcesPath + groupName);
        init();
    }

    private static void init() {
        if (isReWrite == false && isFileExsist) {
            AegisLog.log(fileName + " is already exsit in test resources !");
            return;
        } else {
            deleteQconfigfile();
            changeQconfigEnv(false);
            getQconfigPropertiesToCache();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                AegisLog.error(e);
            }
        }
    }

    public void excute() {
        if (isReWrite == false && isFileExsist) {
            return;
        } else {
            renameCacheFilesToLocal();
            ConfigHandle.touchFileIfNotExsit(resourcesPath + groupName + "/" + fileName, fileName);
            changeQconfigEnv(true);
        }
    }

    public static void deleteQconfigfile() {
        deleteQconfigfile(resourcesPath + groupName, fileName);
        deleteQconfigfile(qconfigTargetDir + groupName, fileName);

    }

    public static Boolean checkIfFileExsist(String Dictionary) {
        File targetFile = new File(Dictionary);
        String[] qconfigTargetDirlist = targetFile.list();
        Boolean result = false;
        if (qconfigTargetDirlist == null) {
            return result;
        }
        for (String name : qconfigTargetDirlist) {
            if (name.equals(fileName)) {
                result = true;
            }
        }
        if (!result) {
            AegisLog.log("check" + resourcesPath + groupName + "/" + fileName + " not exsit!");
        }
        return result;
    }

    public static void deleteQconfigfile(String Dictionary, String filename) {
        String qconfigFileToDelete = Dictionary + "/" + filename;

        File targetFile = new File(Dictionary);
        String[] qconfigTargetDirlist = targetFile.list();
        if (qconfigTargetDirlist == null) {
            return;
        }
        Boolean status = false;
        for (String name : qconfigTargetDirlist) {
            if (name.equals(filename)) {
                status = true;
                Boolean status2 = FileAndDirDeepDeletion.deleteFile(qconfigFileToDelete);
                if (status2) {
                    AegisLog.log("delete " + qconfigFileToDelete + " successed!");
                } else {
                    AegisLog.log("delete " + qconfigFileToDelete + " failed!");
                }
            }
        }
        if (!status) {
            AegisLog.log(qconfigFileToDelete + " not found!");
        }
    }


    private static void getQconfigPropertiesToCache() {
        if (!fileName.isEmpty()) {
            Map<String, String> map = MapConfig.get(groupName, fileName, Feature.DEFAULT).asMap();
            if (map != null) {
                AegisLog.log("下载文件到本地cache: " + getCachePath() + fileName);
            } else {
                AegisLog.log("获取文件 " + getCachePath() + fileName + " 失败");
            }
        }
    }

    private static String getCachePath() {
        return QunarFileUtil.getQunarStore().replace("\\", "/") + "/qconfig/";
    }

    private File newVersionCacheDictionary() {
        //qconfig-client新版本(1.5.11)
        File CONF_HOME = new File(QunarFileUtil.getQunarStore().replace("\\", "/"));
        String appCode = new MockQconfig().getAppCode();
        CONF_HOME = new File(CONF_HOME, appCode + "/qconfig/");
        return CONF_HOME;
    }

    private File oldVersionCacheDictionary() {
        //qconfig-client旧版本(1.2.2)
        File CONF_HOME = new File(QunarFileUtil.getQunarStore().replace("\\", "/"), "qconfig/");
        return CONF_HOME;
    }

    private File cacheDictionary() {
        File CONF_HOME = null;
        if (isNewVersion) {
            CONF_HOME = newVersionCacheDictionary();
        } else {
            CONF_HOME = oldVersionCacheDictionary();
        }
        return CONF_HOME;
    }

    private void renameCacheFilesToLocal() {
        String SNAPSHOT_DIR = "/snapshot2/";
        String property = resourcesPath + groupName + "/";
        File snapFile = new File(cacheDictionary(), groupName + SNAPSHOT_DIR);
        File propertyFile = new File(property);
        snapFile.mkdirs();
        propertyFile.mkdirs();
        boolean isDirectory = snapFile.isDirectory() && propertyFile.isDirectory();
        if (!isDirectory) { // 如果不是文件夹，就返回
            AegisLog.log(snapFile + "不是文件夹！\n or");
            AegisLog.log(propertyFile + "不是文件夹！");
        }
        String[] snapFiles = snapFile.list();
        int i = 0;
        while (i <= 10) {
            if (findFile(snapFiles)) {
                break;
            }
            i++;
        }
    }

    private Boolean findFile(String[] filelist) {
        Boolean isFindFile = false;
        for (int i = 0; i < filelist.length; i++) { // 遍历该文件夹下的所有文件
            String oldsnapFileName = filelist[i];
            File cacheFile = new File(cacheDictionary() + "/" + groupName + "/snapshot2/" + "/" + oldsnapFileName);
            String newFileName = oldsnapFileName.substring(0, oldsnapFileName.lastIndexOf("."));
            newFileName = newFileName.substring(0, newFileName.lastIndexOf(".")).toLowerCase();
            if (newFileName.equals(fileName)) {
                isFindFile = true;
                newFileName = resourcesPath + groupName + "/" + newFileName;
                File newFile = new File(newFileName);
                Boolean result = ConfigHandle.replaceFiles(cacheFile, newFile);
                if (!result) {
                    AegisLog.log("Failed to copy cacheFile to resources: " + newFileName);
                } else {
                    AegisLog.log("Copy cacheFile to resources success: " + newFileName);
                }
            }
        }

        return isFindFile;
    }


}
